﻿using System.Collections;
using System.Collections.Generic;
using LuaInterface;

namespace Framework
{
    /// <summary>
    /// 通用资源加载回调的封装
    /// 做了池化，外部尽量不直接使用该类的构造函数
    /// 不用的时候要放回池内
    /// </summary>
    public sealed class AssetCallBack : SLICacheable
    {
        private static readonly SLObjectPool<AssetCallBack> CbPool = new SLObjectPool<AssetCallBack>(1024);
        public static AssetCallBack GetAssetCallBack(OnAssetLoaded onLoaded, LuaTable luaObj, LuaFunction luaOnLoaded)
        {
            var ret = CbPool.GetObject();
            ret._Init(onLoaded, luaObj, luaOnLoaded);
            return ret;
        }
        public static AssetCallBack GetAssetCallBack(LuaTable luaObj, LuaFunction luaOnLoaded)
        {
            var ret = CbPool.GetObject();
            ret.Init(luaObj, luaOnLoaded);
            return ret;
        }

        public static AssetCallBack GetAssetCallBack(OnAssetLoaded onLoaded)
        {
            var ret = CbPool.GetObject();
            ret.Init(onLoaded);
            return ret;
        }

        public static void RecyleAssetCallBack(AssetCallBack callBack)
        {
            CbPool.PutObject(callBack);
        }

        private OnAssetLoaded onAssetLoadedCb;
        private void Init(OnAssetLoaded onAssetLoaded)
        {
            onAssetLoadedCb = onAssetLoaded;
        }

        private void Init(LuaTable luaObj, LuaFunction luaCb)
        {
            onAssetLoadedLuaCbObj = luaObj;
            onAssetLoadedLuaCb = luaCb;
        }

        private void _Init(OnAssetLoaded onAssetLoaded, LuaTable luaObj, LuaFunction luaCb)
        {
            onAssetLoadedCb = onAssetLoaded;
            onAssetLoadedLuaCbObj = luaObj;
            onAssetLoadedLuaCb = luaCb;
        }

        public bool ClearCallBack(LuaTable luaObj, LuaFunction luaCb)
        {
            if (null != onAssetLoadedLuaCb && onAssetLoadedLuaCb == luaCb && onAssetLoadedLuaCbObj == luaObj)
            {
                onAssetLoadedLuaCb = null;
                onAssetLoadedLuaCbObj = null;
                return true;
            }
            return false;
        }

        public bool ClearCallBack(OnAssetLoaded onAssetLoaded)
        {
            if (null != onAssetLoadedCb && onAssetLoadedCb == onAssetLoaded)
            {
                onAssetLoadedCb = null;
                return true;
            }
            return false;
        }

        public void Reset()
        {
            onAssetLoadedCb = null;
            onAssetLoadedLuaCb = null;
            onAssetLoadedLuaCbObj = null;
        }

        private LuaTable onAssetLoadedLuaCbObj;
        private LuaFunction onAssetLoadedLuaCb;
        internal void Invoke(AssetItem assetItem)
        {
            if (null != onAssetLoadedCb)
            {
                try
                {
                    onAssetLoadedCb(assetItem);
                }
                catch (System.Exception exp)
                {
                    Logger.LogException(exp);
                }
            }
            if (null == onAssetLoadedLuaCb)
            {
                return;
            }
            try
            {
                if (null != onAssetLoadedLuaCbObj)
                {
                    onAssetLoadedLuaCb.Call(onAssetLoadedLuaCbObj, assetItem);
                }
                else
                {
                    onAssetLoadedLuaCb.Call(assetItem);
                }
            }
            catch (System.Exception exp)
            {
                Logger.LogException(exp);
            }
        }
    }
}
